package com.xuhao.didi.oksocket;

import com.xuhao.didi.core.iocore.interfaces.IPulseSendable;
import com.xuhao.didi.core.iocore.interfaces.ISendable;
import com.xuhao.didi.core.pojo.OriginalData;
import com.xuhao.didi.oksocket.adapter.LogAdapter;
import com.xuhao.didi.oksocket.btnview.Ripple;
import com.xuhao.didi.oksocket.data.HandShakeBean;
import com.xuhao.didi.oksocket.data.LogBean;
import com.xuhao.didi.oksocket.data.MsgDataBean;
import com.xuhao.didi.socket.client.impl.client.action.ActionDispatcher;
import com.xuhao.didi.socket.client.sdk.OkSocket;
import com.xuhao.didi.socket.client.sdk.client.ConnectionInfo;
import com.xuhao.didi.socket.client.sdk.client.OkSocketOptions;
import com.xuhao.didi.socket.client.sdk.client.action.SocketActionAdapter;
import com.xuhao.didi.socket.client.sdk.client.connection.IConnectionManager;
import com.xuhao.didi.socket.client.sdk.client.connection.NoneReconnect;
import com.xuhao.didi.socket.common.interfaces.utils.TextUtils;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.miscservices.pasteboard.PasteData;
import ohos.miscservices.pasteboard.SystemPasteboard;

import java.nio.charset.Charset;
import java.util.Arrays;

public class SimpleDemo extends Ability implements Component.ClickedListener, Component.FocusChangedListener {
    private ConnectionInfo mInfo;
    private Ripple mConnect;
    private TextField mTextFieldIp;
    private TextField mTextFieldPort;
    private IConnectionManager mManager;
    private TextField mTextFieldSend;
    private OkSocketOptions mOkOptions;
    private Ripple mClearLog;
    private Ripple mSendBtn;
    private Text mPortHint;
    private Text mPortText;
    private Text mEditHint;
    private Text mIpText;
    private TextUtile animator;
    private ListContainer mSendList;
    private ListContainer mReceList;
    private String mUtf = "utf-8";
    private LogAdapter mSendLogAdapter;
    private LogAdapter mReceLogAdapter;
    private SocketActionAdapter adapter = new SocketActionAdapter() {
        @Override
        public void onSocketConnectionSuccess(ConnectionInfo info, String action) {
            mManager.send(new HandShakeBean());
            mConnect.setText("DisConnect");
            mTextFieldIp.setEnabled(false);
            mTextFieldPort.setEnabled(false);
            animator.chickColor(SimpleDemo.this,mTextFieldIp,mTextFieldPort);
        }

        @Override
        public void onSocketDisconnection(ConnectionInfo info, String action, Exception e) {
            if (e != null) {
                logSend("异常断开(Disconnected with exception):" + e.getMessage());
            } else {
                logSend("正常断开(Disconnect Manually)");
            }
            mConnect.setText("Connect");
            mTextFieldIp.setEnabled(true);
            mTextFieldPort.setEnabled(true);
            animator.chickTextColor(SimpleDemo.this,mTextFieldIp,mTextFieldPort);
        }

        @Override
        public void onSocketConnectionFailed(ConnectionInfo info, String action, Exception e) {
            logSend("连接失败(Connecting Failed)");
            mConnect.setText("Connect");
            mTextFieldIp.setEnabled(true);
            mTextFieldPort.setEnabled(true);
            animator.chickTextColor(SimpleDemo.this,mTextFieldIp,mTextFieldPort);
        }

        @Override
        public void onSocketReadResponse(ConnectionInfo info, String action, OriginalData data) {
            String str = new String(data.getBodyBytes(), Charset.forName(mUtf));
            logRece(str);
        }

        @Override
        public void onSocketWriteResponse(ConnectionInfo info, String action, ISendable data) {
            byte[] bytes = data.parse();
            bytes = Arrays.copyOfRange(bytes, 4, bytes.length);
            String str = new String(bytes, Charset.forName(mUtf));
            logSend(str);
        }

        @Override
        public void onPulseSend(ConnectionInfo info, IPulseSendable data) {
            String str = new String(data.parse(), Charset.forName(mUtf));
            logSend(str);
        }
    };

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_simple_demo);
        findView();
        initData();
    }

    private void initData() {
        mReceLogAdapter = new LogAdapter(this);
        mSendLogAdapter = new LogAdapter(this);
        mSendList.setItemProvider(mSendLogAdapter);
        mReceList.setItemProvider(mReceLogAdapter);
        mSendList.setItemLongClickedListener(new ListContainer.ItemLongClickedListener() {
            @Override
            public boolean onItemLongClicked(ListContainer listContainer, Component component, int i, long l) {
                LogBean log = (LogBean) listContainer.getItemProvider().getItem(i);
                SystemPasteboard systemPasteboard = SystemPasteboard.getSystemPasteboard(SimpleDemo.this);
                PasteData pasteData = PasteData.creatPlainTextData(log.mWho == null ? "" : log.mWho);
                systemPasteboard.setPasteData(pasteData);
                animator.toastText("复制到剪切板", SimpleDemo.this);
                return false;
            }
        });
        mReceList.setItemLongClickedListener(new ListContainer.ItemLongClickedListener() {
            @Override
            public boolean onItemLongClicked(ListContainer listContainer, Component component, int i, long l) {
                LogBean log = (LogBean) listContainer.getItemProvider().getItem(i);
                SystemPasteboard systemPasteboard = SystemPasteboard.getSystemPasteboard(SimpleDemo.this);
                PasteData pasteData = PasteData.creatPlainTextData(log.mWho == null ? "" : log.mWho);
                systemPasteboard.setPasteData(pasteData);
                animator.toastText("复制到剪切板", SimpleDemo.this);
                return false;
            }
        });
        initManager();
    }

    private void initManager() {
        EventHandler mHandler = new EventHandler(EventRunner.getMainEventRunner());
        mInfo = new ConnectionInfo(mTextFieldIp.getText(), Integer.parseInt(mTextFieldPort.getText()));
        mOkOptions = new OkSocketOptions.Builder()
                .setReconnectionManager(new NoneReconnect())
                .setConnectTimeoutSecond(10)
                .setCallbackThreadModeToken(new OkSocketOptions.ThreadModeToken() {
                    @Override
                    public void handleCallbackEvent(ActionDispatcher.ActionRunnable runnable) {
                        mHandler.postTask(runnable);
                    }
                })
                .build();
        mManager = OkSocket.open(mInfo).option(mOkOptions);
        mManager.registerReceiver(adapter);
    }

    private void findView() {
        animator = new TextUtile();
        mEditHint = (Text) findComponentById(ResourceTable.Id_edit_hint);
        mIpText = (Text) findComponentById(ResourceTable.Id_ip_text);
        mPortHint = (Text) findComponentById(ResourceTable.Id_port_hint);
        mPortText = (Text) findComponentById(ResourceTable.Id_port_text);
        mSendList = (ListContainer) findComponentById(ResourceTable.Id_send_list);
        mReceList = (ListContainer) findComponentById(ResourceTable.Id_rece_list);
        mTextFieldIp = (TextField) findComponentById(ResourceTable.Id_ip);
        mTextFieldPort = (TextField) findComponentById(ResourceTable.Id_port);
        mClearLog = (Ripple) findComponentById(ResourceTable.Id_clear_log);
        mConnect = (Ripple) findComponentById(ResourceTable.Id_connect);
        mTextFieldSend = (TextField) findComponentById(ResourceTable.Id_send_et);
        mSendBtn = (Ripple) findComponentById(ResourceTable.Id_send_btn);
        mConnect.setClickedListener(this);
        mSendBtn.setClickedListener(this);
        mClearLog.setClickedListener(this);
        mTextFieldIp.setFocusChangedListener(this);
        mTextFieldPort.setFocusChangedListener(this);
        mTextFieldSend.setFocusChangedListener(this);
        textField();
    }

    private void textField() {
        if (!TextUtils.isEmpty(mTextFieldIp.getText())) {
            mEditHint.setVisibility(Component.VISIBLE);
            mIpText.setVisibility(Component.VERTICAL);
        } else {
            mEditHint.setVisibility(Component.VERTICAL);
            mIpText.setVisibility(Component.VISIBLE);
        }
        if (!TextUtils.isEmpty(mTextFieldPort.getText())) {
            mPortHint.setVisibility(Component.VISIBLE);
            mPortText.setVisibility(Component.VERTICAL);
        } else {
            mPortHint.setVisibility(Component.VERTICAL);
            mPortText.setVisibility(Component.VISIBLE);
        }
    }

    private void logSend(String log) {
        LogBean logBean = new LogBean(System.currentTimeMillis(), log);
        mSendLogAdapter.getDataList().add(0, logBean);
        mSendLogAdapter.notifyDataChanged();
    }

    private void logRece(String log) {
        LogBean logBean = new LogBean(System.currentTimeMillis(), log);
        mReceLogAdapter.getDataList().add(0, logBean);
        mReceLogAdapter.notifyDataChanged();
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_connect:
                if (mManager == null) {
                    return;
                }
                if (!mManager.isConnect()) {
                    initManager();
                    mManager.connect();
                    mTextFieldIp.setEnabled(false);
                    mTextFieldPort.setEnabled(false);
                    animator.chickColor(SimpleDemo.this,mTextFieldIp,mTextFieldPort);
                } else {
                    mConnect.setText("Disconnecting");
                    mManager.disconnect();
                }
                break;
            case ResourceTable.Id_send_btn:
                if (mManager == null) {
                    return;
                }
                if (!mManager.isConnect()) {
                    animator.toastText("Unconnected", SimpleDemo.this);
                } else {
                    String msg = mTextFieldSend.getText();
                    if (TextUtils.isEmpty(msg.trim())) {
                        return;
                    }
                    MsgDataBean msgDataBean = new MsgDataBean(msg);
                    mManager.send(msgDataBean);
                    mTextFieldSend.setText("");
                }
                break;
            case ResourceTable.Id_clear_log:
                mReceLogAdapter.getDataList().clear();
                mSendLogAdapter.getDataList().clear();
                mReceLogAdapter.notifyDataChanged();
                mSendLogAdapter.notifyDataChanged();
                break;
            default:
                break;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mManager != null) {
            mManager.disconnect();
            mManager.unRegisterReceiver(adapter);
        }
    }

    @Override
    public void onFocusChange(Component component, boolean isFocus) {
        ShapeElement errorElement;
        String color = "";
        switch (component.getId()) {
            case ResourceTable.Id_port:
                if (isFocus) {
                    color = "#169E93";
                    errorElement = new ShapeElement(this, ResourceTable.Graphic_background_textfild_color);
                    if (mPortText.getVisibility() == Component.VISIBLE) {
                        animator.animatorField(mPortText, true, 11);
                    }
                } else {
                    color = "#7A7A7A";
                    errorElement = new ShapeElement(this, ResourceTable.Graphic_background_textfild_uncolor);
                    animator.animatorField(mPortText, false, 15);
                }
                mPortHint.setHintColor(new Color(Color.getIntColor(color)));
                mPortText.setHintColor(new Color(Color.getIntColor(color)));
                mTextFieldPort.setBasement(errorElement);
                break;
            case ResourceTable.Id_ip:
                if (isFocus) {
                    color = "#169E93";
                    errorElement = new ShapeElement(this, ResourceTable.Graphic_background_textfild_color);
                    if (mIpText.getVisibility() == Component.VISIBLE) {
                        animator.animatorField(mIpText, true, 11);
                    }
                } else {
                    color = "#7A7A7A";
                    errorElement = new ShapeElement(this, ResourceTable.Graphic_background_textfild_uncolor);
                    animator.animatorField(mIpText, false, 15);
                }
                mEditHint.setHintColor(new Color(Color.getIntColor(color)));
                mIpText.setHintColor(new Color(Color.getIntColor(color)));
                mTextFieldIp.setBasement(errorElement);
                break;
            case ResourceTable.Id_send_et:
                if (isFocus) {
                    errorElement = new ShapeElement(this, ResourceTable.Graphic_background_textfild_color);
                } else {
                    errorElement = new ShapeElement(this, ResourceTable.Graphic_background_textfild_uncolor);
                }
                mTextFieldSend.setBasement(errorElement);
                break;
            default:
                break;
        }
    }
}
